package core.controller
{
	import flash.events.Event;
	import flash.filesystem.File;
	
	import org.aisy.interfaces.IClear;

	public class CopyFile implements IClear
	{
		protected var _targetList:Array;
		protected var _fileFilter:RegExp;
		protected var _dirFilter:RegExp;
		protected var _recursion:Boolean;
		
		public function CopyFile()
		{
		}
		
		protected function getFilePrefix(file:File):String
		{
			var arr:Array = ["isDirectory", "isHidden", "isPackage", "isSymbolicLink"];
			var str:String = ""
			for each (var i:String in arr) {
				str += parseIntInObj(file, i);
			}
			return str;
		}
		
		protected function parseIntInObj(obj:Object, key:String):int
		{
			return obj[key] ? 1 : 0;
		}
		
		protected function __copyFile(sourceFile:File, targetFile:File, callback:Function):void
		{
			sourceFile.addEventListener(Event.COMPLETE, function (e:Event):void
			{
				sourceFile.removeEventListener(e.type, arguments.callee);
				sourceFile.cancel();
				callback(e, targetFile);
				callback = null;
				targetFile = null;
				sourceFile = null;
				e = null;
			});
			sourceFile.copyToAsync(targetFile, true);
		}
		
		protected function __copyFiles(fileArr:Array, parentFile:File = null, index:uint = 0, dir:String = null, prefix:String = null, callback:Function = null):void
		{
			var b:Boolean;
			var c:uint;
			var rArr:Array = [];
			var fuc:Function = function ():void
			{
				c -= c === 0 ? 0 : 1;
				if (c === 0 && b === true) {
					if (null !== callback) callback.apply(null, [rArr, parentFile].slice(0, callback.length));
					rArr = null;
					fuc = null;
					fuc0 = null;
					fuc3 = null;
					callback = null;
					prefix = null;
					dir = null;
					parentFile = null;
					fileArr = null;
				}
			};
			if (null === _targetList || null === fileArr || fileArr.length === 0) {
				fuc();
				return;
			}
			var fuc0:Function = function (e:Event, f:File):void
			{
				switch (e.type) {
					case Event.COMPLETE:
						if (undefined === rArr[0]) rArr[0] = [];
						rArr[0][rArr[0].length] = f;
						break;
				}
				fuc();
				f = null;
				e = null;
			};
			var fuc3:Function = function (arr:Array, file:File):void
			{
				if (undefined === rArr[3]) rArr[3] = [];
				rArr[3][rArr[3].length] = [arr, file];
				fuc();
				file = null;
				arr = null;
			};
			dir = (null !== dir ? dir : "/") + (null !== parentFile ? parentFile.name + "/" : "");
			prefix = null !== prefix ? prefix : "";
			var fPrefix:String;
			var f:File;
			for each (var i:File in fileArr) {
				_fileFilter.lastIndex = 0;
				fPrefix = getFilePrefix(i);
				if (i.isDirectory === true) {
					_dirFilter.lastIndex = 0;
					if (_dirFilter.test(prefix + fPrefix + i.name) === false) {
						i.cancel();
						continue;
					}
					else if (_recursion === true) {
						c++;
						__copyFiles(i.getDirectoryListing(), i, index, dir, prefix + fPrefix, fuc3);
						i.cancel();
						continue;
					}
				}
				else if (_fileFilter.test(prefix + fPrefix + i.name) === false) {
					i.cancel();
					continue;
				}
				f = new File(_targetList[index].replace(/(.+?)(\\+$|\/+$)/ig, "$1") + dir + i.name);
				if (i.url === f.url) {
					if (undefined === rArr[2]) rArr[2] = [];
					rArr[2][rArr[2].length] = i;
				}
				else if (f.exists === true && i.size === f.size && i.modificationDate.getTime() === f.modificationDate.getTime()) {
					if (undefined === rArr[1]) rArr[1] = [];
					rArr[1][rArr[1].length] = i;
				}
				else {
					c++;
					__copyFile(i, f, fuc0);
				}
				f.cancel();
			}
			b = true;
			if (c === 0 && null !== fuc) fuc();
			f = null;
			fPrefix = null;
			dir = null;
			fuc0 = null;
			fuc3 = null;
			prefix = null;
			dir = null;
			fileArr = null;
		}
		
		public function copyFiles(fileArr:Array, parentFile:File = null, callback:Function = null):void
		{
			var rArr:Array;
			var i:uint;
			var f:Function = function (arr:Array, file:File):void
			{
				if (null !== rArr) rArr[rArr.length] = [arr, file];
				if (i === 0) {
					callback.apply(null, [rArr].slice(0, callback.length));
					f = null;
					rArr = null;
					fileArr = null;
					parentFile = null;
					callback = null;
				}
				else {
					i--;
					if (null === rArr) rArr = [];
					__copyFiles(fileArr, parentFile, i, null, null, f);
				}
			};
			if (null !== _targetList) i = _targetList.length;
			f(null, null);
		}
		
		public function setData(data:* = null):void
		{
			_targetList = null;
			_fileFilter = /.*/ig;
			_dirFilter = /.*/ig;
			_recursion = false;
			if (null !== data) {
				if (data.hasOwnProperty("targetList") === true) _targetList = (data.targetList as Array).slice().reverse();
				if (data.hasOwnProperty("fileFilter") === true) _fileFilter = new RegExp(data.fileFilter[0], data.fileFilter[1]);
				if (data.hasOwnProperty("dirFilter") === true) _dirFilter = new RegExp(data.dirFilter[0], data.dirFilter[1]);
				if (data.hasOwnProperty("recursion") === true) _recursion = Boolean(data.recursion);
			}
			data = null;
		}
		
		public function clear():void
		{
			_targetList = null;
			_fileFilter = null;
			_dirFilter = null;
		}
		
	}
}